﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;


namespace spriteData
{
    class Program
    {
      static Dictionary<int, XImage> images =new Dictionary<int,XImage>();
      static Dictionary<int, XModule> modules = new Dictionary<int,XModule>();
      static Dictionary<int, XFrame> frames= new Dictionary<int,XFrame>();
      static Dictionary<int, XAnimation> animations=new Dictionary<int,XAnimation>();

       static  List<string > removeStringEmpty(  string [] str)
        {
            List<string> ret = new List<string>();
            for (int i = 0; i < str.Length; i++)
            {
                if (str[i] != "")
                {
                    ret.Add(str[i]);
                }
            }
            return ret;
        }
       public static void parse(string fileName)
       {
             StreamReader sr = new StreamReader(fileName, Encoding.Default);
            string line;
            while ((line = sr.ReadLine()) != null)
            {
                string temp = line.TrimStart(' ');
                if (temp=="" || temp[0] == '/')
                {
                    continue; 
                }

                if (("IMAGE".Length <= temp.Length) && temp.Substring(0, "IMAGE".Length) == "IMAGE")
                {
                   string [] a= temp.Split(' ');
                   List<string> data = removeStringEmpty(a);
                   XImage imgData= new XImage();
                   imgData.Id =strHexToInt(data[1].TrimEnd(' '));//Convert.ToInt32(data[1].Substring(2));
                   imgData.FileName = data[2].TrimStart('\"').TrimEnd('\"');
                   images.Add(imgData.Id, imgData);          
                }

                if (("MODULES".Length <= temp.Length) && temp.Substring(0, "MODULES".Length) == "MODULES")
                {
                    string mdLine;
                    
                    while ((mdLine = sr.ReadLine()) != null)
                    {
                        string mdTemp = mdLine.TrimStart(' ');
                        if (mdTemp == "" || mdTemp[0] == '{')
                        {
                            continue; 
                        }
                        if (mdTemp[0] == '}')
                        {
                            break;
                        }
                        string[] a = mdTemp.Split('\t');
                        List<string> mdData = removeStringEmpty(a);
                        XModule moduleData = new XModule();
                        moduleData.Id = strHexToInt(mdData[1].TrimEnd(' ')); // Convert.ToInt32(mdData[1].Substring(2));
                        moduleData.ImageId = Convert.ToInt32(mdData[3]);
                        XRectangle rect = new XRectangle(Convert.ToInt32(mdData[4])
                            , Convert.ToInt32(mdData[5])
                            , Convert.ToInt32(mdData[6]),
                            Convert.ToInt32(mdData[7]));
                        moduleData.ModuleRect = rect;
                        modules.Add(moduleData.Id, moduleData);
                        Console.WriteLine(mdTemp);
                    }
                  
                }

                if (("FRAME".Length <= temp.Length) && temp.Substring(0, "FRAME".Length) == "FRAME")
                {
                      string frLine;              
                      XFrame frameData = new XFrame();
                      while ((frLine = sr.ReadLine()) != null)
                      {
                          string frTemp = frLine.TrimStart(' ');
                          if (frTemp == "" || frTemp[0] == '{')
                          {
                              continue;
                          }
                          if (frTemp[0] == '}')
                          {
                              break;
                          }
                          if (frTemp != "" && frTemp.Substring(0, 2) == "FM")
                          {
                              string[] a = frTemp.Split('\t');
                              List<string> frData = removeStringEmpty(a);
                              XModuleInFrame mIFdata = new XModuleInFrame();
                              mIFdata.ModuleId = strHexToInt(frData[1].TrimEnd(' '));// Convert.ToInt32(frData[1].Substring(2));
                              mIFdata.X = Convert.ToInt32(frData[2]);
                              mIFdata.Y = Convert.ToInt32(frData[3]);
                              frameData.modules.Add(mIFdata);
                          }
                          else if (frTemp != "" && frTemp.Substring(0, 2) == "RC")
                          {
                              string[] a = frTemp.Split('\t');
                              List<string> frData = removeStringEmpty(a);
                              XRectangle tempRect = new XRectangle(Convert.ToInt32(frData[1]),
                                 Convert.ToInt32(frData[2]),
                                 Convert.ToInt32(frData[3]),
                                 Convert.ToInt32(frData[4]));
                              frameData.attackRects.Add(tempRect);
                          }
                          else
                          {

                              frameData.Id = strHexToInt(frTemp.TrimEnd(' '));//Convert.ToInt32(frTemp.Substring(2));
                          }
                      }
                      frames.Add(frameData.Id,frameData);
                }

                if (("ANIM".Length <= temp.Length) && temp.Substring(0, "ANIM".Length) == "ANIM")
                {
                    string anLine;
                    XAnimation animData = new XAnimation();
                    while ((anLine = sr.ReadLine()) != null)
                    {
                        string anTemp = anLine.TrimStart(' ');
                        if (anTemp == "" || anTemp[0] == '{')
                        {
                            continue;
                        }
                        if (anTemp[0] == '}')
                        {
                            break;
                        }
                        if (anTemp != "" && anTemp.Substring(0, 2) == "AF")
                        {
                            string[] a = anTemp.Split('\t');
                            List<string> anData = removeStringEmpty(a);
                            XFrameInAnimation fIAnData = new XFrameInAnimation();
                            fIAnData.FrameId = strHexToInt(anData[1].TrimEnd(' '));// Convert.ToInt32(anData[1].Substring(2));
                            fIAnData.Delay = Convert.ToInt32(anData[2]);
                            fIAnData.X = Convert.ToInt32(anData[3]);
                            fIAnData.Y = Convert.ToInt32(anData[4]);
                            animData.frames.Add(fIAnData);
                        }
                        else
                        {
                            animData.Id = strHexToInt(anTemp.TrimEnd(' ')); //Convert.ToInt32(anTemp.Substring(2));
                        }
                    }
                    animations.Add(animData.Id, animData);
                }
               // Console.WriteLine(line);
            }
            //Console.ReadKey();
       }
       static void writeBinary(BinaryWriter bw)
       {
           bw.Write(images.Count);
           foreach (KeyValuePair<int, XImage> img in images)
           {
               img.Value.serial(bw);
           }
           bw.Write(modules.Count);
           foreach (KeyValuePair<int, XModule> module in modules)
           {
               module.Value.serial(bw);
           }
           bw.Write(frames.Count);
           foreach (KeyValuePair<int, XFrame> frame in frames)
           {
               frame.Value.serial(bw);
           }
           bw.Write(animations.Count);
           foreach (KeyValuePair<int, XAnimation> animation in animations)
           {
               animation.Value.serial(bw);
           }
       }
       static void writeXML(string  fileName)
       {
           XmlDocument myXml = new XmlDocument();
           //加载指定的XML文件
           myXml.Load("donotmove.tmp");
           XmlNode root = myXml.SelectSingleNode("/Root");
           XmlElement imgsNode = myXml.CreateElement("Images");
           foreach (KeyValuePair<int,XImage> imgs in images)
           {
               XmlElement imgNode = myXml.CreateElement("Image");
               imgNode.SetAttribute("id", imgs.Value.Id.ToString());
               imgNode.SetAttribute("fileName", imgs.Value.FileName);
               imgsNode.AppendChild(imgNode);
           }
           root.AppendChild(imgsNode);
           XmlElement modulesNode = myXml.CreateElement("Modules");
           foreach (KeyValuePair<int,XModule> module in modules)
           {
               XmlElement moduleNode =  myXml.CreateElement("module");
               moduleNode.SetAttribute("id", module.Value.Id.ToString());
               moduleNode.SetAttribute("ImageId", module.Value.ImageId.ToString());
               moduleNode.SetAttribute("x", module.Value.ModuleRect.X.ToString());
               moduleNode.SetAttribute("y", module.Value.ModuleRect.Y.ToString());
               moduleNode.SetAttribute("width", module.Value.ModuleRect.Width.ToString());
               moduleNode.SetAttribute("height", module.Value.ModuleRect.Height.ToString());
               modulesNode.AppendChild(moduleNode);
           }
           root.AppendChild(modulesNode);
           XmlElement framesNode = myXml.CreateElement("Frames");
           foreach (KeyValuePair<int, XFrame> frame in frames)
           {
               XmlElement frameNode = myXml.CreateElement("frame");
               frameNode.SetAttribute("id", frame.Value.Id.ToString());
                foreach (XModuleInFrame module in frame.Value.modules)
                {
                    XmlElement moduleInFrmaeNode = myXml.CreateElement("moduleInFrame");
                    moduleInFrmaeNode.SetAttribute("ModuleId", module.ModuleId.ToString());
                    moduleInFrmaeNode.SetAttribute("x", module.X.ToString());
                    moduleInFrmaeNode.SetAttribute("y", module.Y.ToString());
                    frameNode.AppendChild(moduleInFrmaeNode);
                }
                foreach (XRectangle rect in frame.Value.attackRects)
                {
                    XmlElement rectFrmaeNode = myXml.CreateElement("attackRects");
                    rectFrmaeNode.SetAttribute("x", rect.X.ToString());
                    rectFrmaeNode.SetAttribute("y", rect.Y.ToString());
                    rectFrmaeNode.SetAttribute("width", rect.Width.ToString());
                    rectFrmaeNode.SetAttribute("height", rect.Height.ToString());
                    frameNode.AppendChild(rectFrmaeNode);
                }
                framesNode.AppendChild(frameNode);
           }
           root.AppendChild(framesNode);
           XmlElement animationsNode = myXml.CreateElement("Animations");
           foreach (KeyValuePair<int, XAnimation> animation in animations)
           {
               XmlElement animationNode = myXml.CreateElement("Animation");
               animationNode.SetAttribute("id", animation.Value.Id.ToString());
               foreach (XFrameInAnimation frame in animation.Value.frames)
               {
                   XmlElement frameInAnimationNode = myXml.CreateElement("frameInAnimation");
                   frameInAnimationNode.SetAttribute("FrameId", frame.FrameId.ToString());
                   frameInAnimationNode.SetAttribute("delay", frame.Delay.ToString());
                   frameInAnimationNode.SetAttribute("X", frame.X.ToString());
                   frameInAnimationNode.SetAttribute("Y", frame.Y.ToString());
                   animationNode.AppendChild(frameInAnimationNode);
               }
               animationsNode.AppendChild(animationNode);
           }
           root.AppendChild(animationsNode);
           string[] tmp = fileName.Split('.');
           myXml.Save(tmp[0]+".xml");
           Console.WriteLine("xml生成成功");
          
       }
        static bool isNum(char  ch)
        {
            if (ch >= '0' && ch <= '9')
            {
                return true;
            }
                return false;
        }
        static int hexCharToInt(char ch)
        {
            switch (ch)
            {
                case 'a':
                case 'A':
                    return 10;
                case 'b':
                case 'B':
                    return 11;
                case 'c':
                case 'C':
                    return 12;
                case 'd':
                case 'D':
           
                    return 13;
                case 'e':
                case 'E':
                    return 14;
                case 'f':
                case 'F':
                    return 15;
                    
            }
            return -1;
        }
        static int strHexToInt(string str)
        {
          int sum = 0;
          for(int i=str.Length-1,k=0;i>1;i--,k++)
          {
              int temp = 1;
              for (int j = 0; j < k; j++)
              {
                  temp = temp * 16;
              }
              if (isNum(str[i]))
              {
                  sum = sum + (str[i] - '0') * temp;
              }
              else
              {
                  sum = sum + hexCharToInt(str[i]) * temp;
              }
                       
          }
          return sum;
        }
        static void Main(string[] args)
        {
             parse(args[0]);
           // parse("NPC_2.sprite");
             writeXML(args[0]);
           // strHexToInt("0x2223f");
            FileStream fs; //声明FileStream对象
            try
            {
               fs = new FileStream(args[1], FileMode.Create); //初始化FileStream对象
           //     fs = new FileStream("aaa.actor", FileMode.Create); //初始化FileStream对象
                BinaryWriter bw = new BinaryWriter(fs); //创建BinaryWriter对象
                writeBinary(bw);
                Console.WriteLine("成功写入");
                bw.Close(); //关闭BinaryWriter对象
                fs.Close(); //关闭文件流
            }
            catch (IOException ex)
            {
                Console.WriteLine(ex.Message);
            }


        }
    }
}
